package com.gph.saviorframework.es.client;

import static org.elasticsearch.node.NodeBuilder.*;

import java.io.InputStream;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;

@Slf4j
@Getter
@Setter
public class EsNodeClientFactoryBean implements FactoryBean<NodeClient>, InitializingBean, DisposableBean {
	private boolean local;
	private boolean enableHttp;
	private String clusterName;
	private NodeClient nodeClient;
	private String pathData;
	private String pathHome;
	private String pathConfiguration;

	EsNodeClientFactoryBean() {
	}

	public EsNodeClientFactoryBean(boolean local) {
		this.local = local;
	}

	@Override
	public NodeClient getObject() throws Exception {
		return nodeClient;
	}

	@Override
	public Class<? extends Client> getObjectType() {
		return NodeClient.class;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		nodeClient = (NodeClient) nodeBuilder().settings(Settings.builder().put(loadConfig())
				.put("http.enabled", String.valueOf(this.enableHttp))
				.put("path.home", this.pathHome)
				.put("path.data", this.pathData))
				.clusterName(this.clusterName).local(this.local).node()
				.client();
	}

	private Settings loadConfig() {
		if (StringUtils.isNotBlank(pathConfiguration)) {
			InputStream stream = getClass().getClassLoader().getResourceAsStream(pathConfiguration);
			if (stream != null) {
				return Settings.builder().loadFromStream(pathConfiguration, getClass().getClassLoader().getResourceAsStream(pathConfiguration)).build();
			}
			log.error(String.format("Unable to read node configuration from file [%s]", pathConfiguration));
		}
		return Settings.builder().build();
	}

	@Override
	public void destroy() throws Exception {
		try {
			log.info("Closing elasticSearch  client");
			if (nodeClient != null) {
				nodeClient.close();
			}
		} catch (final Exception e) {
			log.error("Error closing ElasticSearch client: ", e);
		}
	}
}
